package org.jeecg.modules.edu.base.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhaodui.fxy.StringUtil;
import com.zhaodui.fxy.conHead;
import com.zhaodui.tencent.sdk.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.jdom2.JDOMException;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.base.entity.WxConfigEntity;
import org.jeecg.modules.base.service.impl.WxConfigEntityServiceImpl;

import org.jeecg.modules.edu.buse.entity.EduBuse_07;
import org.jeecg.modules.edu.buse.entity.EduBuse_13;
import org.jeecg.modules.edu.buse.service.IEduBuse_07Service;
import org.jeecg.modules.edu.buse.service.IEduBuse_13Service;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static org.apache.commons.codec.binary.Base64.decodeBase64;

@Slf4j
@Api(value="tenPayController",description="微信",tags="tenPayController")
@Controller
@RequestMapping("/tenPayController")
public class TenpayController {
    @Autowired
    private WxConfigEntityServiceImpl wxConfigEntityService;
    @Autowired
    private CommonUtil commonUtil;
    @Autowired
    private IEduBuse_13Service eduBuse13Service;
    @Autowired
    private IEduBuse_07Service eduBuse07Service;

    @ApiOperation(value = "wxauthv3")
    @RequestMapping(value = "/authv3",method = RequestMethod.GET)
    @ResponseBody
    public Result<?> authV3(@RequestParam(value="CODE", required=false)  String CODE, @RequestParam(value="appCode", required=false)        String appCode) {
        // 验证
        if (StringUtils.isEmpty(CODE)) {
            return Result.error("JSCODE不能为空!");
        }
        System.out.println("appCode======"+appCode);
        if(StringUtil.isEmpty(appCode)){
            appCode = "fxjpay";
        }
        WxConfigEntity wxConfigEntity = wxConfigEntityService.getUserByappcode(appCode);
        String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + wxConfigEntity.getAppId() +
                "&secret=" + wxConfigEntity.getAppSecret() +
                "&code=" +
                CODE+"&grant_type=authorization_code";
        String result= com.xiaoleilu.hutool.http.HttpUtil.get(url);
        JSONObject resultJson = JSONObject.fromObject(result);
        String openid = String.valueOf(resultJson.get("openid"));
         return Result.ok(openid);
     }

    @ApiOperation(value = "wxauthv4")
    @RequestMapping(value = "/authv4",method = RequestMethod.GET)
    @ResponseBody
    public Result<?> authV4(@RequestParam(value="CODE", required=false)  String CODE, @RequestParam(value="appCode", required=false)                String appCode) {
        if (StringUtils.isEmpty(CODE)) {
            return Result.error("JSCODE不能为空!");
        }
        if(StringUtil.isEmpty(appCode)){
            appCode = "fxjpay";
        }
        WxConfigEntity wxConfigEntity = wxConfigEntityService.getUserByappcode(appCode);
        String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + wxConfigEntity.getAppId() +
                "&secret=" + wxConfigEntity.getAppSecret() +
                "&code=" +
                CODE+"&grant_type=authorization_code";
        String result= com.xiaoleilu.hutool.http.HttpUtil.get(url);
        JSONObject resultJson = JSONObject.fromObject(result);
        String openid = String.valueOf(resultJson.get("openid"));
        String access_token = String.valueOf(resultJson.get("access_token"));
        String getUserInfo = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
        String userInfoUrl = getUserInfo.replace("ACCESS_TOKEN", access_token).replace("OPENID", openid);
        String resultres= com.xiaoleilu.hutool.http.HttpUtil.get(userInfoUrl);
        JSONObject resultJsonres = JSONObject.fromObject(resultres);
        return Result.ok(resultJsonres);
    }


    @ApiOperation(value = "getwxuserinfo")
    @RequestMapping(value = "/getwxuserinfo",method = RequestMethod.GET)
    @ResponseBody
    public Result<?> getwxuserinfo(@RequestParam(value="openid", required=false)  String openid,
                                   @RequestParam(value="appCode", required=false)                String appCode){
        if (StringUtils.isEmpty(openid)) {
            return Result.error("JSCODE不能为空!");
        }
        if(StringUtil.isEmpty(appCode)){
            appCode = "fxjpay";
        }
        WxConfigEntity wxConfigEntity = wxConfigEntityService.getUserByappcode(appCode);
//        String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + wxConfigEntity.getAppId() +
//                "&secret=" + wxConfigEntity.getAppSecret() +
//                "&code=" +
//                CODE+"&grant_type=authorization_code";
//        String result= com.xiaoleilu.hutool.http.HttpUtil.get(url);
//        System.out.println("tokenresult="+result);
//        JSONObject resultJson = JSONObject.fromObject(result);
//        String openid = String.valueOf(resultJson.get("openid"));
        String access_token   = commonUtil.getToken(appCode);// 获取token
        String getUserInfo = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
        String userInfoUrl = getUserInfo.replace("ACCESS_TOKEN", access_token).replace("OPENID", openid);
        String resultres= com.xiaoleilu.hutool.http.HttpUtil.get(userInfoUrl);
        System.out.println("resultres="+resultres);
        JSONObject resultJsonres = JSONObject.fromObject(resultres);
        return Result.ok(resultJsonres);
    }

    @ApiOperation(value = "wxauthv5")
    @RequestMapping(value = "/authv5",method = RequestMethod.GET)
    @ResponseBody
    public Result<?> authV5(@RequestParam(value="CODE", required=false)  String CODE, @RequestParam(value="appCode", required=false)                String appCode){
        if (StringUtils.isEmpty(CODE)) {
            return Result.error("JSCODE不能为空!");
        }
        if(StringUtil.isEmpty(appCode)){
            appCode = "fxjpay";
        }
        WxConfigEntity wxConfigEntity = wxConfigEntityService.getUserByappcode(appCode);
        String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + wxConfigEntity.getAppId() +
                "&secret=" + wxConfigEntity.getAppSecret() +
                "&code=" +
                CODE+"&grant_type=authorization_code";
        String result= com.xiaoleilu.hutool.http.HttpUtil.get(url);
        System.out.println("tokenresult="+result);
        JSONObject resultJson = JSONObject.fromObject(result);
        String openid = String.valueOf(resultJson.get("openid"));
        String access_token   = commonUtil.getToken(appCode);// 获取token
        String getUserInfo = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
        String userInfoUrl = getUserInfo.replace("ACCESS_TOKEN", access_token).replace("OPENID", openid);
        String resultres= com.xiaoleilu.hutool.http.HttpUtil.get(userInfoUrl);
        System.out.println("resultres="+resultres);
        JSONObject resultJsonres = JSONObject.fromObject(resultres);
        return Result.ok(resultJsonres);
    }
    @ApiOperation(value = "wxauthv6")
    @RequestMapping(value = "/authv6",method = RequestMethod.GET)
    @ResponseBody
    public Result<?> authV6(@RequestParam(value="JSCODE", required=false)  String JSCODE,
                            @RequestParam(value="appCode", required=false) String appCode,
                            @RequestParam(value="iv", required=false) String iv,
                            @RequestParam(value="encryptedData", required=false) String encryptedData) {
         AES aes = new AES();
        // 验证
        if (StringUtils.isEmpty(JSCODE)) {
            return Result.error("JSCODE不能为空!");
        }
        WxConfigEntity wxConfigEntity = wxConfigEntityService.getUserByappcode(appCode);
        Assert.notNull(JSCODE, "JSCODE can not be empty");

        String url="https://api.weixin.qq.com/sns/jscode2session?appid=" + wxConfigEntity.getAppId() +
                "&secret=" + wxConfigEntity.getAppSecret() +
                "&js_code=" +
                JSCODE+"&grant_type=authorization_code";
        log.info("url=="+url );

        String result= com.xiaoleilu.hutool.http.HttpUtil.get(url);
        log.info("JSCODE=="+JSCODE);

        log.info("authv4=="+ result);

        JSONObject resultJson = JSONObject.fromObject(result);
        log.info("resultJson=="+ resultJson.toString());

        String openid = String.valueOf(resultJson.get("openid"));

        String sessionKey="";
        try{
            sessionKey = String.valueOf(resultJson.get("session_key"));
            StringRedisTemplate redisTemplate = ApplicationContextUtil.getContext().getBean(StringRedisTemplate.class);
            redisTemplate.boundValueOps(openid).set(sessionKey, 7200, TimeUnit.SECONDS);
        }catch (Exception e){

        }
        String userInfo = "";
        try{
            byte[] resultByte = aes.decrypt(decodeBase64(encryptedData.getBytes()), decodeBase64(sessionKey.getBytes()), decodeBase64(iv.getBytes()));
            userInfo = new String(resultByte, "UTF-8");
            log.info("userInfo=="+ userInfo);

            return Result.okandt(userInfo,openid);
        }catch (Exception e){
           return Result.error(e.getMessage());
        }

    }

    @ApiOperation(value = "wxauthv6test")
    @RequestMapping(value = "/authv6test",method = RequestMethod.GET)
    @ResponseBody
    public Result<?> authV6test(@RequestParam(value="JSCODE", required=false)  String JSCODE,
                                @RequestParam(value="appCode", required=false) String appCode,
                                @RequestParam(value="iv", required=false) String iv,
                                @RequestParam(value="encryptedData", required=false) String encryptedData) {



            return Result.error(JSCODE+appCode+iv+encryptedData);


    }
    @RequestMapping(value = "/app/tenpay/prepaybypre", method = RequestMethod.GET)
    @ApiOperation(value="生成预支付订单",produces="application/json",httpMethod="GET")
    @ResponseBody
    public Result<?>  getOrderusepre(
            @RequestParam(value="code", required=false)  String code,
            @RequestParam(value="body", required=false)  String body,

            @RequestParam(value="openid", required=false)  String openid,

             @RequestParam(value="appCode", required=false) String appCode,
            @RequestParam(value="orderNo", required=true) String orderNo,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        System.out.println("appCode======"+appCode);
        if(StringUtil.isEmpty(appCode)){
            appCode = "fxjpay";
        }
        WxConfigEntity wxConfigEntity = wxConfigEntityService.getUserByappcode(appCode);

        if(StringUtil.isNotEmpty(code)){

            String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + wxConfigEntity.getAppId() +
                    "&secret=" + wxConfigEntity.getAppSecret() +
                    "&code=" +
                    code+"&grant_type=authorization_code";
            String result= com.xiaoleilu.hutool.http.HttpUtil.get(url);
            JSONObject resultJson = JSONObject.fromObject(result);
            openid = String.valueOf(resultJson.get("openid"));
        }
        Map<String, Object> map = new HashMap<String, Object>();
        EduBuse_13 buse =  eduBuse13Service.getById(orderNo);
        Result<Map> res = new Result();
        if(buse==null){
            map.put("code", 1);
            map.put("info", "订单不存在，请确认！");
            res.setSuccess(false);
            res.setResult(map);
            return res;
        }

//        FxyGzgl06 fxyGzgl06 = fxyGzgl06Service.getbyquery07(orderNo);
////         if(StringUtil.isNotEmpty(fxyGzgl06.getQuery15())){
////            openid = fxyGzgl06.getQuery15();
////        }
//
//        if("付款成功".equals(fxyGzgl06.getQuery11())){
//            map.put("code", 1);
//            map.put("info", "您已经付款成功，无需支付");
//            return  map;
//         }

        // 获取生成预支付订单的请求类
        PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);
//        String totalFee = request.getParameter("total_fee");
        int total_fee= (int) (Float.valueOf(buse.getQuery05())*100);//(int) (Float.valueOf(fxyGzgl06.getQuery12())*100);
        System.out.println("total:"+total_fee);
        System.out.println("total_fee:" + total_fee);
        prepayReqHandler.setParameter("appid", wxConfigEntity.getAppId());
        if(StringUtil.isEmpty(body)){
            body="付款";
        }
        prepayReqHandler.setParameter("body", body);
        prepayReqHandler.setParameter("mch_id", wxConfigEntity.getMchId());
        String nonce_str = WXUtil.getNonceStr();
        prepayReqHandler.setParameter("nonce_str", nonce_str);
        prepayReqHandler.setParameter("notify_url", wxConfigEntity.getNotifyUrl());
//        String out_trade_no = String.valueOf(UUID.next());
        prepayReqHandler.setParameter("openid",openid);
        prepayReqHandler.setParameter("out_trade_no", orderNo);
        prepayReqHandler.setParameter("spbill_create_ip", request.getRemoteAddr());
        String timestamp = WXUtil.getTimeStamp();
        prepayReqHandler.setParameter("time_start", timestamp);
        System.out.println(String.valueOf(total_fee));
        prepayReqHandler.setParameter("total_fee", String.valueOf(total_fee));
        prepayReqHandler.setParameter("trade_type", "JSAPI");

        /**
         * 注意签名（sign）的生成方式，具体见官方文档（传参都要参与生成签名，且参数名按照字典序排序，最后接上APP_KEY,转化成大写）
         */
        prepayReqHandler.setParameter("sign", prepayReqHandler.createMD5Sign(wxConfigEntity.getAppKey()));
        prepayReqHandler.setGateUrl(ConstantUtil.GATEURL);
        String prepayid = prepayReqHandler.sendPrepay();
        // 若获取prepayid成功，将相关信息返回客户端
        if (prepayid != null && !prepayid.equals("")) {
//            try{
//                fxyGzgl06.setQuery14(out_trade_no);
////                fxyGzgl06.setQuery11("付款成功");
//                fxyGzgl06Service.updateById(fxyGzgl06);
//
//            }catch (Exception e){
//
//            }

            String signs = "appId=" + wxConfigEntity.getAppId() + "&nonceStr=" + nonce_str + "&package=prepay_id="
                    + prepayid + "&signType=MD5"   + "&timeStamp=" + timestamp + "&key="
                    + wxConfigEntity.getAppKey();
            map.put("code", 0);
            map.put("info", "success");
            map.put("prepayid", prepayid);
            /**
             * 签名方式与上面类似
             */
            map.put("sign", MD5Util.MD5Encode(signs, "utf8").toUpperCase());
            map.put("appid", wxConfigEntity.getAppId());
            map.put("timestamp", timestamp);  //等于请求prepayId时的time_start
            map.put("noncestr", nonce_str);   //与请求prepayId时值一致
            map.put("package", "prepay_id="+prepayid);  //固定常量
            map.put("partnerid", ConstantUtil.PARTNER_ID);
            buse.setQuery14("2");
            buse.setQuery15("付款中");
            eduBuse13Service.updateById(buse);
        } else {
            map.put("code", 1);
            map.put("info", "获取prepayid失败");
        }
        res.setSuccess(true);
        res.setResult(map);
        return res;
    }

    @RequestMapping(value = "/app/tenpay/notifybypre")
    @ApiOperation(value="接收微信支付成功通知",produces="application/json",httpMethod="POST")
    public void getnotifyusepre(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        System.out.println("微信支付回调");
        PrintWriter writer = response.getWriter();
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        outSteam.close();
        inStream.close();
        String result = new String(outSteam.toByteArray(), "utf-8");
        System.out.println("微信支付通知结果：" + result);
        Map<String, String> map = null;
        try {
            map = XMLUtil.doXMLParse(result);
        } catch (JDOMException e) {
            e.printStackTrace();
        }
        System.out.println("=========:"+result);
        // 若支付成功，则告知微信服务器收到通知
        if (map.get("return_code").equals("SUCCESS")) {
            if (map.get("result_code").equals("SUCCESS")) {
                System.out.println("充值成功！");
                try{

//                    FxyGzgl06 fxyGzgl06 = fxyGzgl06Service.getbyquery14(map.get("out_trade_no"));
//                    fxyGzgl06.setQuery11("付款成功");
//                    fxyGzgl06Service.updateById(fxyGzgl06);
                }catch (Exception e){

                }
                EduBuse_13 buse =  eduBuse13Service.getById(map.get("out_trade_no"));
                if("2".equals(buse.getQuery14())){
                    buse.setQuery14("3");
                    buse.setQuery15("付款成功");
                    eduBuse13Service.updateById(buse);
                    QueryWrapper<EduBuse_07> wrapper = new QueryWrapper();
                    wrapper.eq("query03",buse.getQuery03());
                    EduBuse_07 buse07 = eduBuse07Service.getOne(wrapper);
                    if(buse07 != null){
                        float ye = Float.parseFloat(buse07.getQuery10()) + Float.parseFloat(buse.getQuery07());
                        int jf = Integer.parseInt(buse07.getQuery09()) + Integer.parseInt(buse.getQuery07());
                        buse07.setQuery09(jf+"");
                        buse07.setQuery10(ye+"");
                        eduBuse07Service.updateById(buse07);
                    }
                }
                System.out.println("订单号："+map.get("out_trade_no"));
                String notifyStr = XMLUtil.setXML("SUCCESS", "");
                writer.write(notifyStr);
                writer.flush();
//                }
            }
        }
    }

    @RequestMapping(value = "/getSignature/{appcode}", method = RequestMethod.POST)
    @ApiOperation(value="获取分享签名",produces="application/json",httpMethod="POST")
    @ResponseBody
    public Map WeixinController(HttpServletResponse response, @RequestBody conHead coninput,
                                @ApiParam(required = true, name = "appcode", value = "appcode") @PathVariable("appcode") String appcode) {
        response.setHeader("Access-Control-Allow-Origin", "*");
        Map ret = new HashMap();
        //获取前台传来的三个参数
        String timestamp = WXUtil.getTimeStamp();
        String nonce_str = WXUtil.getNonceStr();
        String url = "";
        try{
            url =  coninput.getContoUrl();
            System.out.println("url="+url);

        }catch (Exception e){

        }
        String accessToken = "";

        accessToken = commonUtil.getToken(appcode);// 获取token
        System.out.println("accessToken="+accessToken);
        String ticket="";
        try{
            ticket  = WXUtil.getJsApiTicket(accessToken);    // 获取ticket
        }catch (Exception e){

        }
        System.out.println("ticket="+ticket);

//        WxConfigEntity wxConfigEntity = systemService.findUniqueByProperty(WxConfigEntity.class,"appCode",appCode);
        String signs = "jsapi_ticket=" + ticket + "&noncestr=" + nonce_str  +  "&timestamp=" + timestamp+ "&url=" + url  ;
        System.out.println("signs="+signs);

        /**
         * 签名方式与上面类似
         */
        String signature="";

        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(signs.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

//        signature = SHA1.encode(signs);
        System.out.println("signature="+signature);

        ret.put("jsapi_ticket", ticket);
        ret.put("url", url);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        return ret;
    }

    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
}
